﻿Imports System.Reflection

''' <summary>
''' all mystery attributes inherits for this
''' it contains a reference to the declaring type
''' it is instanced only ones (per registrations)
''' </summary>
''' <remarks></remarks>
Public MustInherit Class MysteryClassAttribute
    Inherits Attribute

    Public Property used_in As Type

    ''' <summary>
    ''' this method is called after instancing used in
    ''' </summary>
    ''' <remarks></remarks>
    MustOverride Sub setUp()


End Class

''' <summary>
''' attributes inherting for this one will be return for all class
''' </summary>
''' <remarks></remarks>
Public MustInherit Class MysteryDefaultClassAttribute
    Inherits MysteryClassAttribute


End Class


Public MustInherit Class MysteryPropertyAttribute
    Inherits Attribute

    Public name As String
    Private _used_in As PropertyInfo
    Public Property used_in As PropertyInfo
        Get
            Return _used_in
        End Get
        Set(value As PropertyInfo)
            _used_in = value
            If value IsNot Nothing Then
                _isReadOnly = value.GetSetMethod() Is Nothing
            End If
        End Set
    End Property
    Public Property retrive() As Func(Of Object, Object)
    Public Property save() As Action(Of Object, Object)
    Private _isReadOnly As Boolean
    Public ReadOnly Property isReadOnly As Boolean
        Get
            Return _isReadOnly
        End Get
    End Property

    Public MustOverride Sub setup()

End Class


Public MustInherit Class MysteryPropertyAttributeBaseHelper
    Public MustOverride Function retrive(o As Object) As Object
    Public MustOverride Sub save(o As Object, value As Object)
End Class


Public Class MysteryPropertyAttributeHelper(Of objectType, propertyType)
    Inherits MysteryPropertyAttributeBaseHelper

    Private Property typedRetrive() As Func(Of objectType, propertyType)
    Private Property typedSave() As Action(Of objectType, propertyType)

    Public Sub New(pi As PropertyInfo)
        If pi.GetGetMethod() IsNot Nothing Then
            typedRetrive = [Delegate].CreateDelegate(GetType(Func(Of objectType, propertyType)), pi.GetGetMethod())
        End If
        If pi.GetSetMethod() IsNot Nothing Then
            typedSave = [Delegate].CreateDelegate(GetType(Action(Of objectType, propertyType)), pi.GetSetMethod())
        End If

    End Sub

    Public Overrides Function retrive(o As Object) As Object
        If o Is Nothing Then Return Nothing
        Return typedRetrive()(o)
    End Function

    Public Overrides Sub save(o As Object, value As Object)
        If Me.typedSave Is Nothing Then Exit Sub
        If o Is Nothing Then Exit Sub
        Me.typedSave()(o, value)
    End Sub

End Class

